/*
 * bw_Str.h
 *
 *  Created on: 2018年9月3日
 *  Author: Degang.Wu (windragon@126.com)
 *  Desc:
 */

#ifndef BW_STR_H_
#define BW_STR_H_

#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <string>

using namespace std;

namespace bwcgi {

class BWStr {
public:
	typedef std::vector<std::string> Array;
	typedef Array::iterator iterator;
	typedef std::pair<std::string, std::string> pair;
	typedef std::vector<pair>::iterator pair_iter;

	//
	// from: http://www.cse.yorku.ca/~oz/hash.html
	//
	// Java String's hash algorithm
	// h = 0;
	// for (int i = 0; i < len; i++)
	// {
	//      h = 31*h + str[i];
	// }
	static unsigned long hash(const char* _Str) {
		unsigned long hash_ = 5381;
		unsigned char* str = (unsigned char*) _Str;
		int c;

		while (0 != (c = *str++)) {
			hash_ = ((hash_ << 5) + hash_) + c; /* hash_ * 33 + c */
		}

		return hash_;
	}

	static bool equals(const char* str1, const char* str2) {
#if defined(WINDOWS)
		return 0==_tcscmp(str1, str2);
#else
		size_t len = std::max(strlen(str1), strlen(str2));
		return 0 == strncmp(str1, str2, len);
#endif
	}

	static bool equals(const char* str1, const char* str2, size_t len) {
		return 0 == strncmp(str1, str2, len);
	}

	//
	// 删除字符串起始部分的空白字符或指定字符
	//
	static void trim_left(std::string& str,
			const char* white_space = " \t\r\n") {
		std::string::size_type pos = str.find_first_not_of(white_space);
		if (pos != std::string::npos) {
			str.erase(0, pos);
		}
	}
	;

	//
	// 删除字符串结束部分的空白字符或指定字符
	//
	static void trim_right(std::string& str,
			const char* white_space = " \t\r\n") {
		std::string::size_type pos = str.find_last_not_of(white_space);
		if (pos != std::string::npos) {
			str.erase(pos + 1);
		}
	}
	;

	//
	// 删除字符串两端的空白字符或指定字符
	//
	static void trim(std::string& str, const char* white_space = " \t\r\n") {
		std::string::size_type pos = str.find_last_not_of(white_space);
		if (pos != std::string::npos) {
			str.erase(pos + 1);
			pos = str.find_first_not_of(white_space);
			if (pos != std::string::npos) {
				str.erase(0, pos);
			}
		} else {
			str.erase(str.begin(), str.end());
		}
	}
	;

	//
	// 用指定的分隔符分隔字符串
	//
	// utilities functions
	static int split(Array& results, const std::string& input,
			const std::string& token, bool includeEmpties = true) {
		results.clear();

		std::string::size_type szTotal = input.size();
		std::string::size_type szTk = token.size();

		std::string::size_type lpos = 0;
		std::string::size_type rpos = input.find(token, lpos);
		while (rpos != std::string::npos && lpos < szTotal) {
			std::string str = input.substr(lpos, rpos - lpos);
			if (!str.empty() || includeEmpties) {
				results.push_back(str);
			}

			lpos = rpos + szTk;
			rpos = input.find(token, lpos);
		}

		if (lpos < szTotal) {
			std::string str = input.substr(lpos, szTotal - lpos);
			if (!str.empty() || includeEmpties) {
				results.push_back(str);
			}
		}

		return 0;
	}
	;

	//
	// 用指定的分隔符分隔字符串，对所有结果会trim
	//
	// utilities functions
	static int split_ex(Array& results, const std::string& input,
			const std::string& token, bool includeEmpties = true) {
		results.clear();

		std::string::size_type szTotal = input.size();
		std::string::size_type szTk = token.size();

		std::string::size_type lpos = 0;
		std::string::size_type rpos = input.find(token, lpos);
		while (rpos != std::string::npos && lpos < szTotal) {
			std::string str = input.substr(lpos, rpos - lpos);
			trim(str);
			if (!str.empty() || includeEmpties) {
				results.push_back(str);
			}

			lpos = rpos + szTk;
			rpos = input.find(token, lpos);
		}

		if (lpos < szTotal) {
			std::string str = input.substr(lpos, szTotal - lpos);
			trim(str);
			if (!str.empty() || includeEmpties) {
				results.push_back(str);
			}
		}

		return 0;
	}
	;

	static void replace(std::string& str, char srch, char rep) {
		if (srch == rep) {
			return;
		}

		for (std::string::size_type i = 0; i < str.size(); i++) {
			if (str.at(i) == srch) {
				str[i] = rep;
			}
		}
	}

	static void replace(std::string& str, const char* srch, const char* rep) {
		if (0 == strcmp(srch, rep)) {
			return;
		}
		std::string::size_type pos = 0;
		while ((pos = str.find(srch, pos)) != std::string::npos) {
			str.replace(pos, strlen(srch), rep);
			pos++;
		}
	}

	static void replace(std::string& str, const std::string& srch,
			std::string& rep) {
		if (srch == rep) {
			return;
		}
		std::string::size_type pos = 0;
		while ((pos = str.find(srch, pos)) != std::string::npos) {
			str.replace(pos, srch.size(), rep);
			pos++;
		}
	}

	static int colorstrtoint(std::string& str) {
		std::string new_str = str=str.replace(str.find("#"),1,"0x");
		return std::stoi(new_str,NULL,16);
	}

};

} /* namespace bwcgi */

#endif /* BW_STR_H_ */
